package com.kitty.record.kittyio.nio.two;

import io.netty.handler.ssl.util.SelfSignedCertificate;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;

/**
 * @Description
 * @Author SHEN
 * @Date 2021/2/18
 */
public class Server {

    private Selector selector;

    private ServerSocketChannel serverSocketChannel;

    public static final int PORT = 9999;

    public Server() {

        //1.获取通道
        try {
            serverSocketChannel = ServerSocketChannel.open();

            serverSocketChannel.configureBlocking(false);

            serverSocketChannel.bind(new InetSocketAddress(PORT));

            selector = Selector.open();

            serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);


        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public void listen(){

        System.out.println("监听线程："+Thread.currentThread().getName());

        try {
            while (selector.select() > 0){
                System.out.println("开始一轮事件处理！！！");

                Iterator<SelectionKey> it = selector.selectedKeys().iterator();

                while (it.hasNext()){

                    SelectionKey sk = it.next();

                    if(sk.isReadable()){

                        readData(sk);

                    }else if(sk.isAcceptable()){

                        SocketChannel socketChannel = serverSocketChannel.accept();

                        socketChannel.configureBlocking(false);

                        System.out.println(socketChannel.getRemoteAddress()+"上线！！！！");

                        socketChannel.register(selector,SelectionKey.OP_READ);

                    }

                    it.remove();

                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }


    }

    private void readData(SelectionKey sk) {

        SocketChannel channel = null;

        ByteBuffer buffer = ByteBuffer.allocate(1024);

        try {

            channel = (SocketChannel) sk.channel();
            int count = channel.read(buffer);
            if(count > 0){

                String msg = new String(buffer.array());

                System.out.println("from 客户端"+msg);

                sendInfoToOtherClient(msg,channel);

            }


        } catch (IOException e) {

            try {
                System.out.println(channel.getRemoteAddress()+"离线了！！！");

                sk.cancel();

                channel.close();

            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }


    }

    private void sendInfoToOtherClient(String msg, SocketChannel channel) throws IOException {

        System.out.println("服务器转发消息中。。。");
        System.out.println("服务器转发数据给客户端程序："+Thread.currentThread().getName());

        for (SelectionKey key : selector.keys()) {

            Channel targetChannel = key.channel();

            if(targetChannel instanceof SocketChannel && targetChannel != channel){

                SocketChannel dest = (SocketChannel) targetChannel;

                ByteBuffer buffer = ByteBuffer.wrap(msg.getBytes());

                dest.write(buffer);
            }
        }
    }

    public static void main(String[] args) {

        Server group = new Server();

        group.listen();

    }
}
